package code;

import java.util.LinkedList;

public class Link {
	public double m_capacity_, // Kbyte/s
			m_delay_, // s
			m_max_queuesize_, // kbytes
			m_current_queuesize_, // kbytes
			m_last_trans_time_; // s
	Node m_source_, m_destination_;
	LinkedList<Packet> m_buffer_;

	public Link(double m_capacity_, double m_delay_, double m_max_queuesize_,
			Node m_source_, Node m_destination_) {
		this.m_capacity_ = m_capacity_;
		this.m_delay_ = m_delay_;
		this.m_max_queuesize_ = m_max_queuesize_;
		this.m_current_queuesize_ = 0;
		this.m_last_trans_time_ = 0;
		this.m_source_ = m_source_;
		this.m_destination_ = m_destination_;
		this.m_buffer_ = new LinkedList<Packet>();

		this.m_source_.add_link_(this);
		System.out.println("Link Generation Complete");
	}

	public Link() {
	}

	void get_packet_(Packet p) { // packet arrive action
		p.m_nexthop_ = m_destination_;
		p.m_nexthopIP_ = m_destination_.IPadd_;
		p.m_link_ = this;
		double idle_queuesize = m_max_queuesize_ - m_current_queuesize_;
		if (p.m_size_ > idle_queuesize) {
			System.out
					.printf("Time %f: One packet is dropped: source %d, router %d\n",Global.TIME,
							p.m_sourceIP_, m_source_.IPadd_);
		} else {
			if (m_buffer_.isEmpty()) {
				m_current_queuesize_ = p.m_size_;
				m_last_trans_time_ = Global.TIME;
				Event e = new Event(3, p.m_size_ / m_capacity_ + Global.TIME,
						m_destination_.IPadd_, p, m_destination_, null);
				Global.EVENTQUEUE.putinqueue_(e);
//				System.out.printf("1st pkt,%f,%f\n", m_current_queuesize_,
//						Global.TIME);
			} else {
				m_current_queuesize_ += p.m_size_;
				Event e = new Event(3, m_current_queuesize_ / m_capacity_
						+ m_last_trans_time_, m_destination_.IPadd_, p,
						m_destination_, null);
				Global.EVENTQUEUE.putinqueue_(e);
//				System.out.printf("2nd pkt,%f,%f\n", m_current_queuesize_,
//						Global.TIME);
						
			}
			m_buffer_.addLast(p);
		}

	}

	void dequeue(Packet p) {
		Packet p1 = this.m_buffer_.removeFirst();
		if (p1 == p) {
			this.m_last_trans_time_ = Global.TIME;
			m_current_queuesize_ -= p.m_size_;
//			System.out.printf("Current queue size %f\n", m_current_queuesize_);
			Event e = new Event(1, Global.TIME + m_delay_,
					m_destination_.IPadd_, p, m_destination_, null);
			Global.EVENTQUEUE.putinqueue_(e);
		} else
			System.out.println("Someting worng happens in the queue!");
	}

}
